﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ModeloMagiPack.Entidades;
using DALMagiPack.Funcionalidad;
using System.IO;
using System.Drawing;

namespace BLLMagiPack.Managers
{
    public class BLLOrden: BLLMagiPack
    {
        public void CargarOrden(OrdenCompleta ordenCompleta)
        {
            DALMagiPack<Orden> dalOrden = new DALMagiPack<Orden>();

            dalOrden.IniciarConexión();
            dalOrden.IniciarTransacción();

            DALMagiPack<OrdenCaja> dalCaja = new DALMagiPack<OrdenCaja>() { Connection = dalOrden.Connection, Transaction = dalOrden.Transaction };
            DALMagiPack<OrdenComplementos> dalComplementos = new DALMagiPack<OrdenComplementos>() { Connection = dalOrden.Connection, Transaction = dalOrden.Transaction };
            DALMagiPack<OrdenDiseñoCaja> dalDiseñoCaja = new DALMagiPack<OrdenDiseñoCaja>() { Connection = dalOrden.Connection, Transaction = dalOrden.Transaction };

            dalOrden.Insertar(ordenCompleta.Orden);
            ordenCompleta.Caja.IdOrden = ordenCompleta.Diseño.IdOrden = ordenCompleta.Complementos.IdOrden = ordenCompleta.Orden.IdOrden;
            dalCaja.Insertar(ordenCompleta.Caja);
            dalComplementos.Insertar(ordenCompleta.Complementos);
            dalDiseñoCaja.Insertar(ordenCompleta.Diseño);

            dalOrden.ConfirmarTransacción();
            dalOrden.CerrarConexión();
        }

        public void ModificarOrden(OrdenCompleta ordenCompleta)
        {
            DALMagiPack<Orden> dalOrden = new DALMagiPack<Orden>();
            OrdenDiseñoCaja diseñoVieja;

            dalOrden.IniciarConexión();
            dalOrden.IniciarTransacción();

            DALMagiPack<OrdenCaja> dalCaja = new DALMagiPack<OrdenCaja>() { Connection = dalOrden.Connection, Transaction = dalOrden.Transaction };
            DALMagiPack<OrdenComplementos> dalComplementos = new DALMagiPack<OrdenComplementos>() { Connection = dalOrden.Connection, Transaction = dalOrden.Transaction };
            DALMagiPack<OrdenDiseñoCaja> dalDiseñoCaja = new DALMagiPack<OrdenDiseñoCaja>() { Connection = dalOrden.Connection, Transaction = dalOrden.Transaction };

            dalOrden.Modificar(ordenCompleta.Orden);
            dalCaja.Modificar(ordenCompleta.Caja);
            dalComplementos.Modificar(ordenCompleta.Complementos);

            diseñoVieja = dalDiseñoCaja.Traer(new OrdenDiseñoCaja() { IdOrdenDiseñoCaja = ordenCompleta.Diseño.IdOrdenDiseñoCaja },
                        new List<Filtro>() { new Filtro() { Columna = NombresColumnas.IdOrdenDiseñoCaja, Tipo = TipoFiltro.Equal } }).FirstOrDefault();
            dalDiseñoCaja.Modificar(ordenCompleta.Diseño);

            dalOrden.ConfirmarTransacción();
            dalOrden.CerrarConexión();

            if (ordenCompleta.Diseño.ArchivoFoto != diseñoVieja.ArchivoFoto)
                EliminarImagen(diseñoVieja.ArchivoFoto);
        }

        public void EliminarOrden(int idOrden)
        {
            List<string> elementos = new List<string>();

            BLLOrdenFactura bllOrdenFactura = new BLLOrdenFactura();
            if (bllOrdenFactura.PoseeFacturaPorOrden(idOrden))
                elementos.Add("facturas de clientes");

            BLLOrdenFacturaProveedor bllOrdenFacturaProveedor = new BLLOrdenFacturaProveedor();
            if (bllOrdenFacturaProveedor.PoseeFacturaPorOrden(idOrden))
                elementos.Add("facturas de proveedores");

            ValidarDependencia(elementos, "orden", "", false);

            OrdenCompleta completa = TraerOrdenCompleteta(idOrden);
            DALMagiPack<Orden> dalOrden = new DALMagiPack<Orden>();

            dalOrden.IniciarConexión();
            dalOrden.IniciarTransacción();

            DALMagiPack<OrdenCaja> dalCaja = new DALMagiPack<OrdenCaja>() { Connection = dalOrden.Connection, Transaction = dalOrden.Transaction };
            DALMagiPack<OrdenComplementos> dalComplementos = new DALMagiPack<OrdenComplementos>() { Connection = dalOrden.Connection, Transaction = dalOrden.Transaction };
            DALMagiPack<OrdenDiseñoCaja> dalDiseñoCaja = new DALMagiPack<OrdenDiseñoCaja>() { Connection = dalOrden.Connection, Transaction = dalOrden.Transaction };

            dalCaja.Eliminar(completa.Caja);
            dalComplementos.Eliminar(completa.Complementos);
            dalDiseñoCaja.Eliminar(completa.Diseño);
            dalOrden.Eliminar(completa.Orden);

            dalOrden.ConfirmarTransacción();
            dalOrden.CerrarConexión();

            if (completa.Diseño.ArchivoFoto != null)
                EliminarImagen(completa.Diseño.ArchivoFoto);
        }

        public OrdenCompleta TraerOrdenCompleteta(int idOrden)
        {
            OrdenCompleta completa = new OrdenCompleta();
            DALMagiPack<Orden> dalOrden = new DALMagiPack<Orden>();
            DALMagiPack<OrdenCaja> dalCaja = new DALMagiPack<OrdenCaja>() { Connection = dalOrden.Connection, Transaction = dalOrden.Transaction };
            DALMagiPack<OrdenComplementos> dalComplementos = new DALMagiPack<OrdenComplementos>() { Connection = dalOrden.Connection, Transaction = dalOrden.Transaction };
            DALMagiPack<OrdenDiseñoCaja> dalDiseñoCaja = new DALMagiPack<OrdenDiseñoCaja>() { Connection = dalOrden.Connection, Transaction = dalOrden.Transaction };

            completa.Orden = dalOrden.Traer(new Orden() { IdOrden = idOrden }, new List<Filtro>() { new Filtro() { Columna = NombresColumnas.IdOrden, Tipo = TipoFiltro.Equal } }).First();
            completa.Caja = dalCaja.Traer(new OrdenCaja() { IdOrden = idOrden }, new List<Filtro>() { new Filtro() { Columna = NombresColumnas.IdOrden, Tipo = TipoFiltro.Equal } }).First();
            completa.Diseño = dalDiseñoCaja.Traer(new OrdenDiseñoCaja() { IdOrden = idOrden }, new List<Filtro>() { new Filtro() { Columna = NombresColumnas.IdOrden, Tipo = TipoFiltro.Equal } }).First();
            completa.Complementos = dalComplementos.Traer(new OrdenComplementos() { IdOrden = idOrden }, new List<Filtro>() { new Filtro(){ Columna = NombresColumnas.IdOrden, Tipo = TipoFiltro.Equal} }).First();

            return completa;
        }

        public List<Orden> TraerOrdenesPorModelo(int? idModelo)
        {
            DALMagiPack<Orden> dalOrdenes = new DALMagiPack<Orden>();
            return dalOrdenes.Traer(new Orden() { IdModeloCaja = idModelo }, new List<Filtro>() { new Filtro() { Columna = NombresColumnas.IdModeloCaja, Tipo = TipoFiltro.Equal } });
        }

        public List<Orden> TraerOrdenes(int? idCliente, int? idModeloCaja)
        {
            DALMagiPack<Orden> dalOrden = new DALMagiPack<Orden>();
            Orden datosFiltro = new Orden();
            List<Filtro> opciones = new List<Filtro>();

            if(idCliente != null)
            {
                datosFiltro.IdCliente = (int) idCliente;
                Filtro filtroCliente = new Filtro() { Columna = NombresColumnas.IdCliente, Tipo = TipoFiltro.Equal };
                opciones.Add(filtroCliente);
            }

            if (idModeloCaja != null)
            {
                datosFiltro.IdModeloCaja = (int) idModeloCaja;
                Filtro filtroModeloCaja = new Filtro() { Columna = NombresColumnas.IdModeloCaja, Tipo = TipoFiltro.Equal };
                opciones.Add(filtroModeloCaja);
            }

            return dalOrden.Traer(datosFiltro, opciones);
        }

        public Orden TraerOrden(int idOrden)
        {
            DALMagiPack<Orden> dalOrden = new DALMagiPack<Orden>();
            return dalOrden.Traer(new Orden() { IdOrden = idOrden }, new List<Filtro>() { new Filtro() { Columna = NombresColumnas.IdOrden, Tipo = TipoFiltro.Equal } }).FirstOrDefault();
        }

        public OrdenCaja TraerCaja(int idOrden)
        {
            DALMagiPack<OrdenCaja> dalCaja = new DALMagiPack<OrdenCaja>();
            return dalCaja.Traer(new OrdenCaja() { IdOrden = idOrden }, new List<Filtro>() { new Filtro() { Columna = NombresColumnas.IdOrden, Tipo = TipoFiltro.Equal } }).FirstOrDefault();
        }

        public Dictionary<decimal, DateTime> TraerHistorial(int idCliente, int idModeloCaja)
        {
            List<Orden> ordenes = new BLLOrden().TraerOrdenes(idCliente, idModeloCaja).OrderByDescending(o => o.Fecha).ToList();
            Dictionary<decimal, DateTime> putairas = new Dictionary<decimal, DateTime>();
            DALMagiPack<OrdenCaja> dalOrdenCaja = new DALMagiPack<OrdenCaja>();

            foreach (Orden orden in ordenes)
            {
                OrdenCaja caja = dalOrdenCaja.Traer(new OrdenCaja() { IdOrden = orden.IdOrden }, new List<Filtro>() { new Filtro() { Columna = NombresColumnas.IdOrden, Tipo = TipoFiltro.Equal } }).FirstOrDefault();

                KeyValuePair<decimal, DateTime> ultimoPrecio = putairas.LastOrDefault();

                if(ultimoPrecio.Key != caja.Precio)
                    putairas.Add(caja.Precio, orden.Fecha);
            }

            return putairas;
        }

        public bool PoseeOrdenesPorVendedor(int idVendedor)
        {
            DALMagiPack<Orden> dalOrdenes = new DALMagiPack<Orden>();
            Orden filtro = new Orden() { IdVendedor = idVendedor };
            List<Filtro> opciones = new List<Filtro>() { new Filtro(){ Columna = NombresColumnas.IdVendedor, Tipo = TipoFiltro.Like} };
            int cantidad = dalOrdenes.Contar(filtro, opciones);
            return cantidad > 0;
        }

        public bool PoseeOrdenesPorCliente(int idCliente)
        {
            DALMagiPack<Orden> dalOrdenes = new DALMagiPack<Orden>();
            Orden filtro = new Orden() { IdCliente = idCliente };
            List<Filtro> opciones = new List<Filtro>() { new Filtro() { Columna = NombresColumnas.IdCliente, Tipo = TipoFiltro.Like } };
            int cantidad = dalOrdenes.Contar(filtro, opciones);
            return cantidad > 0;
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="archivoFoto">Nombre completo del archivo origen a ser copiado</param>
        /// <returns></returns>
        public string GuardarImagen(string archivoFoto)
        {
            string[] array = archivoFoto.Split(new string[] { @"\" }, StringSplitOptions.RemoveEmptyEntries);
            string[] array2 = array[array.Length - 1].Split(new string[] { @"." }, StringSplitOptions.RemoveEmptyEntries);
            string nombreArchivo = Guid.NewGuid() + "." + array2[array2.Length - 1];
            string nombreParaGuardar = CarpetaFotos + nombreArchivo;

            if (!Directory.Exists(CarpetaFotos))
                Directory.CreateDirectory(CarpetaFotos);

            if (File.Exists(archivoFoto))
            {
                Image imagen = Image.FromFile(archivoFoto);
                Bitmap nuevaImagen = ResizeImage(imagen, 453, 377);
                nuevaImagen.Save(nombreParaGuardar);
            }
            
            return nombreArchivo;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="nombreFoto">Solamente el nombre de la foto como se guarda en base de datos</param>
        public void EliminarImagen(string nombreFoto)
        {
            string pathCompleto = CarpetaFotos + nombreFoto;

            if (File.Exists(pathCompleto))
                File.Delete(pathCompleto);
        }

        #region Cálculos

        public static double CalcularSuperficie(string medidas)
        {
            string[] array = medidas.ToLower().Split(new string[] { @"x" }, StringSplitOptions.RemoveEmptyEntries);
            double alto = 0;
            double largo = 0;

            if (array.Length == 2 && double.TryParse(array[0], out alto) && double.TryParse(array[1], out largo))
                return ((alto / 1000) * (largo / 1000));
            else
                return 0;
        }

        #endregion
    }
}
